#ifndef __MUTEX_H
#define __MUTEX_H

#include "../rtx/rtx_os.h"
#include "../utils/nocopyable.h"

namespace rtos {

class Mutex : private utils::NoCopyable {
public:
    void init(const char *name = "other") {
        osMutexAttr_t attr;
        attr.name = name;
        attr.attr_bits = osMutexRecursive + osMutexRobust + osMutexPrioInherit;
        attr.cb_mem = m_cb_mem;
        attr.cb_size = osRtxMutexCbSize;
        m_id = osMutexNew(&attr);
    }

    inline osStatus_t lock(uint32_t timeout = osWaitForever) {
        return osMutexAcquire(m_id, timeout);
    }

    inline osStatus_t un_lock() { return osMutexRelease(m_id); }

private:
    osMutexId_t m_id;
    uint64_t m_cb_mem[(osRtxMutexCbSize + 7) / 8];
};

struct AutoLock : private utils::NoCopyable {

    inline AutoLock(Mutex &m) : lock(m) { m.lock(); }

    inline ~AutoLock() { lock.un_lock(); }

private:
    Mutex &lock;
};

#define AUTO_LOCK(m) rtos::AutoLock __(m)

} // namespace rtos

#endif
